package com.rykj.qxj.server.util;

import com.rykj.qxj.server.util.object.StringUtils;
import lombok.extern.log4j.Log4j;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 所属类别:http请求工具类<br/>
 * Author:<a href="mailto:lilong@tsinghuabigdata.com">lilong</a> <br/>
 * Date:2015-1-14 上午10:42:27<br/>
 * Version:1.0 <br/>
 */
@Log4j
public class HttpClientUtils {
    private static Logger logger = Logger.getLogger(HttpClientUtils.class);
    final static int TIMEOUT = 15 * 1000;
    final static String CHARSET = "UTF-8";

    /**
     * 方法描述:发送POST请求<br/>
     * Author:<a href="mailto:lilong@tsinghuabigdata.com">lilong</a> <br/>
     * Date:2015-1-14 上午10:42:40<br/>
     * Version:1.0 <br/>
     *
     * @param url          请求URL（全路径）
     * @param params(请求参数)
     * @return 返回结果
     */
    public static String post(String url, Map<String, String> params) throws Exception {
        URL urlObject = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) urlObject.openConnection();
        connection.setConnectTimeout(TIMEOUT);
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
        connection.setRequestProperty("Accept", "application/json");
        connection.setRequestProperty("Accept-Charset", CHARSET);

        connection.connect();
        OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream(), CHARSET);
        writer.write(requestData(params));
        writer.flush();
        writer.close();

        InputStream stream = (connection.getResponseCode() != 200) ? connection.getErrorStream() : connection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream, CHARSET));
        StringBuffer result = new StringBuffer();

        String output;
        while ((output = reader.readLine()) != null) {
            result.append(output);
        }
        writer.close();
        stream.close();
        reader.close();
        connection.disconnect();
        return result.toString();
    }

    public static String get(String url) throws IOException {
        System.setProperty("jsse.enableSNIExtension", "false");
        URL urlObject = new URL(url);
        HttpURLConnection connection = (HttpURLConnection) urlObject.openConnection();
        connection.setConnectTimeout(TIMEOUT);
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.setRequestMethod("GET");
//		connection.setRequestProperty("Cookie", "wxsid=xdfL80D/bNsv8ehz;wxuin=1219688940");
        connection.connect();

        InputStream stream = (connection.getResponseCode() != 200) ? connection.getErrorStream() : connection.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(stream, CHARSET));
        StringBuffer result = new StringBuffer();

        String output;
        while ((output = reader.readLine()) != null) {
            result.append(output);
        }
        stream.close();
        reader.close();
        connection.disconnect();
        return result.toString();
    }

    /**
     * 方法描述:构建请求参数 <br/>
     * Author:<a href="mailto:lilong@tsinghuabigdata.com">lilong</a> <br/>
     * Date:2015-1-14 上午10:40:44<br/>
     * Version:1.0 <br/>
     *
     * @param params
     * @return
     */
    private static String requestData(Map<String, String> params) {
        // 构建请求参数
        if (params == null) {
            return null;
        }
        StringBuffer buffer = new StringBuffer();
        for (Entry<String, String> entry : params.entrySet()) {
            buffer.append(entry.getKey());
            buffer.append("=");
            buffer.append(entry.getValue());
            buffer.append("&");
        }
        int bufferLen = buffer.length();
        if (bufferLen > 1) {
            buffer.substring(0, bufferLen - 1);
        }
        return buffer.toString();
    }

    /**
     * put方式请求
     *
     * @param url  接口地址
     * @param json 请求参数(json格式)
     * @return
     * @throws Exception
     */
    public static String put(String url, String json) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPut put = new HttpPut(url);
        put.setHeader("Content-Type", "application/json;charset=UTF-8");
        put.setEntity(new StringEntity(json));

        //Create a custom response handler
        ResponseHandler<String> responseHandler = getResponse();
        String responseBody = httpClient.execute(put, responseHandler);
        logger.info(responseBody);
        return responseBody;
    }

    /**
     * post方式请求
     *
     * @param url  接口地址
     * @param json 请求参数(json格式)
     * @return
     * @throws Exception
     */
    public static String post(String url, String json) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        post.setHeader("Content-Type", "application/json;charset=UTF-8");
        post.setEntity(new StringEntity(json, "utf-8"));

        //Create a custom response handler
        ResponseHandler<String> responseHandler = getResponse();
        String responseBody = httpClient.execute(post, responseHandler);
        logger.info(responseBody);
        return responseBody;
    }

    /**
     * delete方式请求
     *
     * @param url  接口地址
     * @param json 请求参数(json格式)
     * @return
     * @throws Exception
     */
    public static String delete(String url, String json) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpDelete delete = new HttpDelete(url);
        delete.setHeader("Content-Type", "application/json;charset=UTF-8");

        //Create a custom response handler
        ResponseHandler<String> responseHandler = getResponse();
        String responseBody = httpClient.execute(delete, responseHandler);
        logger.info(responseBody);
        return responseBody;
    }

    private static ResponseHandler<String> getResponse() {
        ResponseHandler<String> responseHandler = response -> {
            int status = response.getStatusLine().getStatusCode();
            response.setHeader("Content-Type", "application/json;charset=UTF-8");
            if (status >= 200 && status < 300) {
                HttpEntity entity = response.getEntity();
                return entity != null ? EntityUtils.toString(entity) : null;
            } else {
                throw new ClientProtocolException("Unexpection response status: " + status);
            }
        };
        return responseHandler;
    }

    public static void main(String[] args) throws Exception {
        downloadFile("http://192.168.0.241:7771/temp/face/192.168.0.188_8000_1/0.jpg", "\\01-hs\\img\\test.jpg");
    }

    public static void downloadFile(String fileUrl, String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();
        OutputStream os = new FileOutputStream(file);
        URL url = new URL(fileUrl);
        InputStream is = url.openStream();
        byte[] buff = new byte[1024];
        while (true) {
            int readed = is.read(buff);
            if (readed == -1) {
                break;
            }
            byte[] temp = new byte[readed];
            System.arraycopy(buff, 0, temp, 0, readed);
            os.write(temp);
        }
        is.close();
        os.close();
    }

    /**
     * form data 提交方式
     *
     * @param url
     * @param param
     * @return
     */
    public static String doPost(String url, Map<String, Object> param) {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            // 创建Http Post请求
            HttpPost httpPost = new HttpPost(url);
            // 创建参数列表
            if (param != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : param.keySet()) {
                    paramList.add(new BasicNameValuePair(key, param.get(key).toString()));
                }
                // 模拟表单
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "utf-8");
                httpPost.setEntity(entity);
            }
            // 执行http请求
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                logger.debug("错误异常 {}", e);
            }
        }
        return resultString;
    }
    /**
     * post方式请求
     *
     * @param url  接口地址
     * @param json 请求参数(json格式)
     * @return
     * @throws Exception
     */
    public static String doTokenPost(String url,String token, String json) throws IOException {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        post.setHeader("Content-Type", "application/json;charset=UTF-8");
        post.setEntity(new StringEntity(json, "utf-8"));
        post.setHeader("token", token);
        //Create a custom response handler
        ResponseHandler<String> responseHandler = getResponse();
        String responseBody = httpClient.execute(post, responseHandler);
        logger.info(responseBody);
        return responseBody;
    }

    public static String doGetToken(String url, Map<String, Object> data) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建参数队列
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        if(data != null && data.size() > 0){
            data.forEach((k, v) -> params.add(new BasicNameValuePair(k, v.toString())));
        }
        //参数转换为字符串
        String paramsStr = EntityUtils.toString(new UrlEncodedFormEntity(params, "UTF-8"));
        url = url + "?" + paramsStr;

        // 创建httpget.
        HttpGet httpget = new HttpGet(url);
        if (CollectionUtils.isEmpty(data) && StringUtils.isNotEmpty(data.get("token"))){
            httpget.setHeader("token", (String) data.get("token"));
        }
        // 执行get请求.
        CloseableHttpResponse response = httpclient.execute(httpget);
        // 获取响应实体
        HttpEntity entity = response.getEntity();
        // 打印响应状态
        String result = "";
        if (entity != null) {
            result =  EntityUtils.toString(entity);
            response.close();
        }
        return result;
    }



    public static String doGet(String url, Map<String, Object> data) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建参数队列
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        if(data != null && data.size() > 0){
            data.forEach((k, v) -> params.add(new BasicNameValuePair(k, v.toString())));
        }
        //参数转换为字符串
        String paramsStr = EntityUtils.toString(new UrlEncodedFormEntity(params, "UTF-8"));
        url = url + "?" + paramsStr;

        // 创建httpget.
        HttpGet httpget = new HttpGet(url);
        // 执行get请求.
        CloseableHttpResponse response = httpclient.execute(httpget);
        // 获取响应实体
        HttpEntity entity = response.getEntity();
        // 打印响应状态
        String result = "";
        if (entity != null) {
            result =  EntityUtils.toString(entity);
            response.close();
        }
        return result;
    }

//    /**
//     * 上传图片(二进制的方式)
//     *
//     * @param url
//     * @param filePath
//     * @throws Exception
//     */
//    public static String upload(String url, String filePath) throws IOException {
//        CloseableHttpClient m_HttpClient = HttpClients.createDefault();
//        HttpPost httpPost = new HttpPost(url);
//        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(6000).build();
//        httpPost.setConfig(requestConfig);
//        byte[] bytes = FileUtil.getImageBinary(filePath);
//        httpPost.setEntity(new ByteArrayEntity(bytes));
//        httpPost.setHeader("Content-type", "binary/octet-stream");
//        CloseableHttpResponse httpResponse = m_HttpClient.execute(httpPost);
//        String resultString = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
//        return resultString;
//    }

//    /**
//     * 上传文件
//     * @param url 接口
//     * @param builder 参数
//     * @return
//     * @throws IOException
//     */
//    public static String upload(String url,MultipartEntityBuilder builder) throws IOException{
//        CloseableHttpClient httpClient = HttpClients.createDefault();
//        String result = "";
//        HttpPost httpPost = new HttpPost(url);
////        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
////        builder.addBinaryBody("file", file.getInputStream(), ContentType.MULTIPART_FORM_DATA, fileName);// 文件流
////        builder.addTextBody("filename", fileName);// 类似浏览器表单提交，对应input的name和value
//        HttpEntity entity = builder.build();
//        httpPost.setEntity(entity);
//        HttpResponse response = httpClient.execute(httpPost);// 执行提交
//        HttpEntity responseEntity = response.getEntity();
//        if (responseEntity != null) {
//            // 将响应内容转换为字符串
//            result = EntityUtils.toString(responseEntity, Charset.forName("UTF-8"));
//        }
//        System.out.println(result);
//        return result;
//    }
}
